package string;

import framework.AbstractTest;
import utils.Log;


/**
 * Created by shane on 2018/6/11.
 */
public class StringTest extends AbstractTest {

    private static final String URL_KEY_CORPID = "\\{\\{corpid}}";
    private static final String URL_KEY_CORPID_NOCOMPILE = "{{corpid}}";
    private static final String URL_KEY_USERID = "\\{\\{userid\\}\\}";
    private static final String URL_KEY_DINGTALKID = "\\{\\{dingtalkid\\}\\}";

    private static final String SQLITECIPHER = "WWtDbDFad29rOEtkZzNlbg==";
    private static final String SQLITECIPHER2 = "5757744462444661643239724F45746B5A7A4E6C62673D3D";

    private final static String[] emojis = new String[]{
        "😀", "😁", "😂", "😃", "😄", "😅", "😆", "😇", "😉", "😊", "😋", "😌", "😍", "😎", "😏", "😐", "😒",
        "😓", "👍", "😕", "😖", "😗", "😘", "😙", "😚", "😛", "😜", "😝", "😞", "😟", "😠", "😡", "😢", "😣",
        "😤", "😥", "😦", "😧", "😨", "😩", "😬", "😭", "😮", "😯", "😰", "😱", "😲", "😳", "😴", "😵", "😶",
        "😷", "🙁", "🙂", "🙃", "🙄", "🤐", "🤑", "🤒", "🤓", "🤔", "🤕", "🤗", "🤠", "🤢", "🤣", "🤤", "🤥",
        "🤧", "☺", "😸", "😹", "😺", "😻", "😼", "😽", "😾", "😿", "🙀", "🙅", "🙆", "🙇", "🙋", "🙍", "🙎",
        "🙏", "🙈", "🙉", "🙊", "👿", "😈", "✊", "✋", "✌", "👆", "👇", "👌", "👍", "👎", "👏", "🙌", "🤛",
        "🤜", "✂", "✅", "✈", "✏", "✒", "✔", "✖", "✨", "💰", "🌹", "💋", "✉", "💌", "💖", "💗", "💘", "💝"
    };

    private final static String[] emojis2 = new String[]{
        "😀", "😁", "😂", "😃", "😄", "😅", "😆", "😇", "😉", "😊", "😋", "😌", "😍", "😎", "😏", "😐", "😒",
        "😓", "👍", "😕", "😖", "😗", "😘", "😙", "😚", "😛", "😜", "😝", "😞", "😟", "😠", "😡", "😢", "😣",
        "😤", "😥", "😦", "😧", "😨", "😩", "😬", "😭", "😮", "😯", "😰", "😱", "😲", "😳", "😴", "😵", "😶",
        "😷", "🙁", "🙂", "🙃", "🙄", "🤐", "🤑", "🤒", "🤓", "🤔", "🤕", "🤗", "🤠", "🤢", "🤣", "🤤", "🤥",
        "🤧", "☺", "😸", "😹", "😺", "😻", "😼", "😽", "😾", "😿", "🙀", "🙅", "🙆", "🙇", "🙋", "🙍", "🙎",
        "🙏", "🙈", "🙉", "🙊", "👿", "😈", "✊", "✋", "✌", "👆", "👇", "👌", "👍", "👎", "👏", "🙌", "🤛",
        "🤜", "✂", "✅", "✈", "✏", "✒", "✔", "✖", "✨", "💰", "🌹", "💋", "✉", "💌", "💖", "💗", "💘", "💝"
    };

    public static final String GET_TYPE_DEFAULT_JS = "(args){var type=0;"
        + "if(typeof args==='string'){type=1}" +
        "else if(typeof args==='number'){type=2}" +
        "else if(typeof args==='boolean'){type=3}" +
        "else if(typeof args==='function'){type=4}" +
        "else if(args instanceof Array){type=6}" +
        "else if(typeof args==='object'){type=5}" +
        "return type}";

    public static final String GET_TYPE_DEFAULT_JS2 = "(args){var type=0;if(typeof args==='string'){type=1}" +
        "else if(typeof args==='number'){type=2}" +
        "else if(typeof args==='boolean'){type=3}" +
        "else if(typeof args==='function'){type=4}" +
        "else if(args instanceof Array){type=6}" +
        "else if(typeof args==='object'){type=5}" +
        "return type}";

    static String bytesToString(byte[] bytes) {
        StringBuffer var1 = new StringBuffer();

        for(int i = 0; i < bytes.length; ++i) {
            if ((bytes[i] & 255) < 16) {
                var1.append("0" + Integer.toHexString(bytes[i] & 255));
            } else {
                var1.append(Integer.toHexString(bytes[i] & 255));
            }
        }

        return var1.toString();
    }

    @Override
    public void test(String[] args) {
        super.test(args);
        Log.vn("a == b ?" + (GET_TYPE_DEFAULT_JS == GET_TYPE_DEFAULT_JS2));
        // t();
        testReplace();
        Log.vn("bytes:" + bytesToString(SQLITECIPHER.getBytes()));
    }

    void t() {
        String url = "https://developer.android.com/reference/java/util/regex/Pattern.html?corpid={{corpid}}";

        String formatValue = url;
        int index = url.indexOf(URL_KEY_CORPID_NOCOMPILE);
        if (index >= 0) {
            formatValue = url.replaceAll(URL_KEY_CORPID, "1234");
            Log.vn("formatValue2:" + formatValue);
        }

        Log.vn("formatValue:" + formatValue);

        String s = getVideoFormatDuration(9);
        Log.vn(s);

        String x = useOfIntern("formatValue:");
        Log.vn(x);

        testFormat();
        testFormat2();

        testInternV1();
        testInternV2();

        Log.vn("testEmoji:" + testEmoji());
    }

    boolean testEmoji() {
        for (int i = 0; i < emojis.length; i++) {
            if (!emojis[i].equals(emojis2[i])) {
                return false;
            }
        }

        return true;
    }

    private static String getVideoFormatDuration(long durationInSeconds) {
        if (durationInSeconds <= 0) {
            return "";
        }

        long seconds = durationInSeconds % 60;
        long minutes = durationInSeconds / 60;
        return String.format("%d:%02d", minutes, seconds);
    }

    public static void main(String[] args) {
        new StringTest().test(null);
        Log.vn("-5: " + Integer.toBinaryString(-5));

        Log.vn("bytes:" + SQLITECIPHER.getBytes());
    }


    private static String useOfIntern(String s) {
        if (s != null) {
            return s.intern();
        }

        return null;
    }

    /***
     * 既然 intern() 方法有这些好处，为什么不经常使用呢？原因在于它会降低代码效率。
     * refs: http://www.importnew.com/21836.html
     */
    private static final int MAX = 1000000;
    private static final String[] DB_DATA = {"1", "2", "3", "4", "5", "6", "13", "14",
            "21", "22", "23", "24", "31", "32", "33", "34",};

    static void testInternV1() {
        long t = System.currentTimeMillis();
        String[] arr = new String[MAX];
        for (int i = 0; i < MAX; i++) {
            arr[i] = new String(DB_DATA[i % 10]);
            // and: arr[i] = new String(DB_DATA[i % 10]).intern();
        }
        System.out.println("testInternV1:" + (System.currentTimeMillis() - t) + "ms");
        System.gc();
        System.out.println(arr[0]);
    }

    static void testInternV2() {
        long t = System.currentTimeMillis();
        String[] arr = new String[MAX];
        for (int i = 0; i < MAX; i++) {
//            arr[i] = new String(DB_DATA[i % 10]);
             arr[i] = new String(DB_DATA[i % 10]).intern();
        }
        System.out.println("testInternV2:" + (System.currentTimeMillis() - t) + "ms");
        System.gc();
        System.out.println(arr[0]);
    }


    static void testFormat() {
        String str = null;
        str = String.format("Hi,%s", "王力");
        System.out.println(str);
        str = String.format("Hi,%s:%s.%s", "王南", "王力", "王张");
        System.out.println(str);
        System.out.printf("字母a的大写是：%c %n", 'A');
        System.out.printf("3>7的结果是：%b %n", 3 > 7);
        System.out.printf("100的一半是：%d %n", 100 / 2);
        System.out.printf("100的16进制数是：%x %n", 100);
        System.out.printf("100的8进制数是：%o %n", 100);
        System.out.printf("50元的书打8.5折扣是：%f 元%n", 50 * 0.85);
        System.out.printf("上面价格的16进制数是：%a %n", 50 * 0.85);
        System.out.printf("上面价格的指数表示：%e %n", 50 * 0.85);
        System.out.printf("上面价格的指数和浮点数结果的长度较短的是：%g %n", 50 * 0.85);
        System.out.printf("上面的折扣是%d%% %n", 85);
        System.out.printf("字母A的散列码是：%h %n", 'A');
    }

    static void testFormat2() {
        String str = null;
        //$使用
        str = String.format("格式参数$的使用：%1$d,%2$s", 99, "abc");
        System.out.println(str);
        //+使用
        System.out.printf("显示正负数的符号：%+d与%d%n", 99, -99);
        //补O使用
        System.out.printf("最牛的编号是：%03d%n", 7);
        //空格使用
        System.out.printf("Tab键的效果是：% 8d%n", 7);
        //.使用
        System.out.printf("整数分组的效果是：%,d%n", 9989997);
        //空格和小数点后面个数
        System.out.printf("一本书的价格是：% 50.5f元%n", 49.8);
    }

    static void testReplace() {
        String pdd = "拼多多，拼多多，拼得多，省得多:-";
        String value = "遵守\"本分\"价值观";

        String res = pdd.replace("-", value);
        Log.vn("res:" + res);
    }
}
